﻿using System.Collections.Generic;
using System.Linq;
using System.Windows.Input;
using BingleMaps.Models.GoogleMaps;
using BingleMaps.Services;
using BingleMaps.ViewModels;
using GalaSoft.MvvmLight.Command;
using Microsoft.Phone.Controls;
using Serialization;

namespace BingleMaps.Models
{
	public class SearchQuery : NotifyPropertyChanged
	{
		#region Private Members

		private bool _hasInputChanged;

		#endregion


		#region Constructors

		public SearchQuery()
		{
			CommandSuggest = new RelayCommand<PopulatingEventArgs>(OnSuggest);
		}

		#endregion


		#region Public Properties

		public string Input
		{
			get { return _input; }
			set
			{
				if (_input != null)
				{
					_hasInputChanged = true;
				}
				SetProperty(ref _input, value, InputPropertyName);
				if (value != null && (SelectedSuggestion == null || SelectedSuggestion.Description == value))
				{
					return;
				}
				Suggestions = null;
			}
		}

		private string _input;
		private const string InputPropertyName = "Input";

		[DoNotSerialize]
		public IEnumerable<Suggestion> Suggestions
		{
			get { return _suggestions; }
			set { SetProperty(ref _suggestions, value, SuggestionsPropertyName); }
		}

		private IEnumerable<Suggestion> _suggestions;
		private const string SuggestionsPropertyName = "Suggestions";

		public Suggestion SelectedSuggestion
		{
			get { return _selectedSuggestion; }
			set { SetProperty(ref _selectedSuggestion, value, SelectedSuggestionPropertyName); }
		}

		private Suggestion _selectedSuggestion;
		private const string SelectedSuggestionPropertyName = "SelectedSuggestion";

		#endregion


		#region Commands

		[DoNotSerialize]
		public ICommand CommandSuggestionComplete { get; set; }

		[DoNotSerialize]
		public ICommand CommandSuggest { get; private set; }

		#endregion


		#region Event Handling

		private void OnSuggest(PopulatingEventArgs e)
		{
			if (!_hasInputChanged || (Suggestions != null && Suggestions.Any(s => s.Description == Input)))
			{
				e.Cancel = true;
				return;
			}
			var center = ViewModelLocator.MainStatic.MapCenter;
			GoogleMapsServices.GetPredictions(
				new Location
				{
					Lat = center.Latitude,
					Lng = center.Longitude
				},
				Input,
				predictions =>
				{
					Suggestions = predictions;
					if (CommandSuggestionComplete != null && CommandSuggestionComplete.CanExecute(null))
					{
						CommandSuggestionComplete.Execute(null);
					}
				});
		}

		#endregion
	}
}
